package com.cykj.pos.service.impl;

import com.cykj.common.annotation.DataSource;
import com.cykj.common.core.domain.entity.SysUser;
import com.cykj.common.enums.DataSourceType;
import com.cykj.common.utils.SecurityUtils;
import com.cykj.pos.domain.*;
import com.cykj.pos.domain.dto.CashOutDTO;
import com.cykj.pos.domain.dto.CashOutVO;
import com.cykj.pos.domain.dto.SubmitGrantDetailDTO;
import com.cykj.pos.service.*;
import com.cykj.pos.util.*;
import com.cykj.pos.websocket.server.WebSocketServer;
import com.cykj.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.lang3.StringUtils;
import com.cykj.pos.mapper.BizMicroInfoMapper;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 报件小微商户信息Service业务层处理
 *
 * @author ningbingwu
 * @date 2021-01-11
 */
@Service
public class BizMicroInfoServiceImpl extends ServiceImpl<BizMicroInfoMapper, BizMicroInfo> implements IBizMicroInfoService {

    @Autowired
    BizMicroInfoMapper bizMicroInfoMapper;
    @Autowired
    private IBizWalletService walletService;
    @Autowired
    private IBizMicroInfoService bizMicroInfoService;
    @Autowired
    private IBizMicroInfoService microInfoService;
    @Autowired
    private IBizCashoutRecordsService cashoutRecordsService;
    @Autowired
    private IBizCashoutFeeService cashoutFeeService;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private IBizMerchantService merchantService;
    @Autowired
    private IBizMerchBillService merchBillService;

    @Autowired
    ISysUserService sysUserService;
    @Override
    @DataSource(DataSourceType.SLAVE)
    public List<BizMicroInfo> queryList(BizMicroInfo bizMicroInfo) {
        LambdaQueryWrapper<BizMicroInfo> lqw = Wrappers.lambdaQuery();
        if (bizMicroInfo.getMerchId() != null){
            lqw.eq(BizMicroInfo::getMerchId ,bizMicroInfo.getMerchId());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchBank())){
            lqw.eq(BizMicroInfo::getMerchBank ,bizMicroInfo.getMerchBank());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchBankCardno())){
            lqw.eq(BizMicroInfo::getMerchBankCardno ,bizMicroInfo.getMerchBankCardno());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchBankCity())){
            lqw.eq(BizMicroInfo::getMerchBankCity ,bizMicroInfo.getMerchBankCity());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchBankMobile())){
            lqw.eq(BizMicroInfo::getMerchBankMobile ,bizMicroInfo.getMerchBankMobile());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchBankCard())){
            lqw.eq(BizMicroInfo::getMerchBankCard ,bizMicroInfo.getMerchBankCard());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcardPositive())){
            lqw.eq(BizMicroInfo::getMerchIdcardPositive ,bizMicroInfo.getMerchIdcardPositive());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcardBack())){
            lqw.eq(BizMicroInfo::getMerchIdcardBack ,bizMicroInfo.getMerchIdcardBack());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcardHand())){
            lqw.eq(BizMicroInfo::getMerchIdcardHand ,bizMicroInfo.getMerchIdcardHand());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcard())){
            lqw.eq(BizMicroInfo::getMerchIdcard ,bizMicroInfo.getMerchIdcard());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcardName())){
            lqw.like(BizMicroInfo::getMerchIdcardName ,bizMicroInfo.getMerchIdcardName());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getMerchIdcardDuedate())){
            lqw.eq(BizMicroInfo::getMerchIdcardDuedate ,bizMicroInfo.getMerchIdcardDuedate());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getVar1())){
            lqw.eq(BizMicroInfo::getVar1 ,bizMicroInfo.getVar1());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getVar2())){
            lqw.eq(BizMicroInfo::getVar2 ,bizMicroInfo.getVar2());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getVar3())){
            lqw.eq(BizMicroInfo::getVar3 ,bizMicroInfo.getVar3());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getVar4())){
            lqw.eq(BizMicroInfo::getVar4 ,bizMicroInfo.getVar4());
        }
        if (StringUtils.isNotBlank(bizMicroInfo.getVar5())){
            lqw.eq(BizMicroInfo::getVar5 ,bizMicroInfo.getVar5());
        }
        return this.list(lqw);
    }
    @Override
    public int updataMicroInfo(BizMicroInfo bizMicroInfo) {
        int bizMicroInfos=bizMicroInfoMapper.updataMicroInfo(bizMicroInfo);
        return bizMicroInfos;
    }
    @DataSource(DataSourceType.SLAVE)
    @Override
    public BizMicroInfo getBizMicroInfoByMerchId(Long merchId){
        LambdaQueryWrapper<BizMicroInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(BizMicroInfo::getMerchId ,merchId);
        return this.getOne(lqw);
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public boolean idCordIsExist(String card) {
        LambdaQueryWrapper<BizMicroInfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(BizMicroInfo::getMerchIdcard ,card);
        List<BizMicroInfo> list = list(lqw);
        if(list==null || list.size()==0)
            return false;
        return true;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public CashOutVO getMerchMicroInfoByUserIdAndAccountType(CashOutDTO cashOutDTO) {
        Long userId = cashOutDTO.getUserId();
        CashOutVO cashOutVO =  bizMicroInfoMapper.selectMerchMicroInfoByUserIdAndChannel(userId,cashOutDTO.getChannelId());
        // 处理一下吧
        if(cashOutDTO.getAccountType()==1){ // 分润账户
            // 把补贴账户的内容设置为null
            cashOutVO.setRewardAmount(null);
            cashOutVO.setCoverAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(cashOutDTO.getAccountType()==2){//补贴账户
            // 把分润账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setCoverAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(cashOutDTO.getAccountType()==3){//服务费账户
            // 把结算账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setRewardAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(cashOutDTO.getAccountType()==4){//流量费账户
            // 把结算账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setRewardAmount(null);
            cashOutVO.setCoverAmount(null);
        }
        // 银行卡需要最后四位
        String cardNo = cashOutVO.getMerchBankCardno();
        if(!"".equals(cardNo) && cardNo.length()>4 && cashOutDTO.getEncryptionCardno()==1){
            cardNo = cardNo.substring(cardNo.length()-4);
            cashOutVO.setMerchBankCardno(cardNo);
        }
        return cashOutVO;
    }

    @Override
    public boolean confirmPaymentPassword(CashOutDTO cashOutDTO) {
        SysUser sysUser = sysUserService.selectUserById(cashOutDTO.getUserId());
        // 加密输入的密码
        String inputPaymentPassword = cashOutDTO.getPaymentPassword();
        String dbPaymentPassword = sysUser.getPaymentPassword();

        if(SecurityUtils.matchesPassword(inputPaymentPassword,dbPaymentPassword))
            return true;
        return false;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public CashOutVO getXinLongMerchMicroInfoByUserIdAndAccountType(SubmitGrantDetailDTO submitGrantDetailDTO) {
        Long userId = submitGrantDetailDTO.getUserId();
        CashOutVO cashOutVO =  bizMicroInfoMapper.selectMerchMicroInfoByUserId(userId);
        // 处理一下吧
        if(submitGrantDetailDTO.getAccountType()==1){ // 分润账户
            // 把补贴账户的内容设置为null
            cashOutVO.setRewardAmount(null);
            cashOutVO.setCoverAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(submitGrantDetailDTO.getAccountType()==2){//补贴账户
            // 把分润账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setCoverAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(submitGrantDetailDTO.getAccountType()==3){//服务费账户
            // 把结算账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setRewardAmount(null);
            cashOutVO.setFlowAmount(null);
        }else if(submitGrantDetailDTO.getAccountType()==4){//流量费账户
            // 把结算账户的内容设置为null
            cashOutVO.setProfitAmount(null);
            cashOutVO.setRewardAmount(null);
            cashOutVO.setCoverAmount(null);
        }
        // 银行卡需要最后四位
        String cardNo = cashOutVO.getMerchBankCardno();
        if(!"".equals(cardNo) && cardNo.length()>4 && submitGrantDetailDTO.getEncryptionCardno()==1){
            cardNo = cardNo.substring(cardNo.length()-4);
            cashOutVO.setMerchBankCardno(cardNo);
        }
        return cashOutVO;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public CashOutVO getXinLongMerchMicroInfoByUserIdAndAccountType1(SubmitGrantDetailDTO submitGrantDetailDTO) {
        Long userId = submitGrantDetailDTO.getUserId();
        CashOutVO cashOutVO =  bizMicroInfoMapper.selectMerchMicroInfoByUserId(userId);
        // 处理一下吧
//        if(submitGrantDetailDTO.getAccountType()==1){ // 结算账户
//            // 把奖励账户的内容设置为null
//            cashOutVO.setRewardAmount(null);
//        }else if(submitGrantDetailDTO.getAccountType()==2){//奖励账户
//            // 把结算账户的内容设置为null
//            cashOutVO.setProfitAmount(null);
//        }
        // 银行卡需要最后四位
        String cardNo = cashOutVO.getMerchBankCardno();
        if(!"".equals(cardNo) && cardNo.length()>4 && submitGrantDetailDTO.getEncryptionCardno()==1){
            cardNo = cardNo.substring(cardNo.length()-4);
            cashOutVO.setMerchBankCardno(cardNo);
        }
        return cashOutVO;
    }

    @Override
    public String getDfTypeByMerchId(String merchId) {
        return bizMicroInfoMapper.getdfTypeByMerchId(merchId);
    }

    @Override
    public String getDeptIdByuserId(String userId) {
        return bizMicroInfoMapper.getDeptIdByuserId(userId);
    }

    @Override
    public BizBehalfPayment getBehalfPaymentByDeptId(String deptId) {
        return bizMicroInfoMapper.getBehalfPaymentByDeptId(deptId);
    }

    @Override
    public BizBehalfPayment getBehalfPaymentByCode(String code) {
        return bizMicroInfoMapper.getBehalfPaymentByCode(code);
    }



    @Override
    public String notifyPayment(String requestJson,String code) throws Exception {
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByCode(code);
        org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj
                = new org.springframework.boot.configurationprocessor.json.JSONObject(requestJson);
//        String reqMsgId = requestJsonObj.getString("reqMsgId");
        String headStr = requestJsonObj.getString("head");
        headStr = URLDecoder.decode(headStr, "UTF-8");
        String cipherStr = requestJsonObj.getString("cipher");
        String bodyStr = requestJsonObj.getString("body");
        String signStr = requestJsonObj.getString("sign");
//        String hqyKey = HqyApiContantsV2.HQY_MER_KEY_V2;
        String hqyKey = bizBehalfPayment.getBehalfKey();
        String callBackState = "FAILURE";
        if (StringUtils.isNotBlank(bodyStr)) {
            headStr = URLEncoder.encode(headStr, "UTF-8");
            String cipherRes = Md5Util.getMd5(headStr + "#" + bodyStr, hqyKey, "UTF-8").toUpperCase();
            if (!cipherRes.equalsIgnoreCase(cipherStr)) {
                return "FAILURE";
            }
            //商户模式
//            File pubPlatKeyFile = ResourceUtils.getFile(HqyApiContantsV2.HQY_MER_PUBLIC_KEY_PATH_V2);
            File pubPlatKeyFile = ResourceUtils.getFile(bizBehalfPayment.getBehalfPublicKey());
            if (!RSAPemCoder.verify(bodyStr.getBytes(), RSAPemCoder.getPublicKeyFromPem(pubPlatKeyFile), signStr)) {
                return "FAILURE";
            }
            // body AES解密
            String srcResBody = AESUtilApi.decrypt(bodyStr, hqyKey);
            srcResBody = URLDecoder.decode(srcResBody, "UTF-8");
            org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj_
                    = new org.springframework.boot.configurationprocessor.json.JSONObject(srcResBody);
            System.out.println("srcResBody ==" + srcResBody);
            String batchNo = requestJsonObj_.getString("batchNo");
            String paymentBatchDetailInfoList = requestJsonObj_.getString("paymentBatchDetailInfoList");
            JSONArray requestJsonObjs = new JSONArray(paymentBatchDetailInfoList);
            String remitResult = requestJsonObjs.getJSONObject(0).getString("remitResult");
            String remitResultMsg = requestJsonObjs.getJSONObject(0).getString("remitResultMsg");
            BizCashoutRecords cashoutRecords =
                    cashoutRecordsService.getCashoutRecordsByCustOrderNo(batchNo);
            Long userId = cashoutRecords.getCreateBy();
            if("S".equals(remitResult)){
                System.out.println("------------------------支付成功----------------------------");
                // 成功 // 发消息
                String var3 = cashoutRecords.getVar3();
                String var4 = cashoutRecords.getVar4();
                BigDecimal serviceFee = new BigDecimal(var3);
                BigDecimal rateFee = new BigDecimal(var4);
                BigDecimal totalServiceFee = serviceFee.add(rateFee);
                BigDecimal orderAmt = cashoutRecords.getCashoutAmount().subtract(totalServiceFee);
                String walletAmount = cashoutRecords.getVar5();
                String paymentMess = "您的提现已成功到账，提现金额：" + cashoutRecords.getCashoutAmount() + "元，实际到账金额为："
                        + orderAmt + "元，账户余额为：" + walletAmount + "元。提现到" + cashoutRecords.getDealBank() +
                        ",提现订单号是：" + cashoutRecords.getVar2();
                System.out.println(paymentMess);
                BizMessageRecords paymentMessageRecords = new BizMessageRecords();
                paymentMessageRecords.setMsgContent(paymentMess);// 消息内容
                paymentMessageRecords.setMsgType(4); // 消息类型  4
                paymentMessageRecords.setReadStatus(0); // 消息未读
                paymentMessageRecords.setAdviceType(1); // 业务消息
                webSocketServer.sendInfo(userId, paymentMessageRecords);// 发送消息
                // 生账单
                BizMerchBill merchBill = new BizMerchBill();
                BizMerchant merchant = merchantService.getMerchantByUserId(userId); //商户信息
                merchBill.setMerchId(merchant.getMerchId());// 商户id
                merchBill.setMerchName(merchant.getMerchName());// 商户名称
                merchBill.setBillType("4");// 款项类型 1-返现 2-分润 3-奖励 4-提现 5-押金
                Date date = cashoutRecords.getCreateTime();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                merchBill.setBillDate(sdf.format(date)); //账单日期  与提现日期一致
                merchBill.setCashoutRecordsId(cashoutRecords.getCashoutId());// 提现id
                merchBill.setAmount(cashoutRecords.getCashoutAmount().negate()); // 提现存的是负值
                merchBillService.save(merchBill); // 存账单数据
                // 提现记录  更新状态为 1
                cashoutRecords.setCashoutStatus("1");
                cashoutRecords.setVar1(batchNo);
                cashoutRecords.setMsgId(paymentMessageRecords.getMsgId()); // 存储记录中对应的消息id
                cashoutRecordsService.saveOrUpdate(cashoutRecords);
//                //返上级税差
//                try {
//                    this.with(merchant,cashoutRecords);
//                }catch (Exception e){
//                    System.out.println("返上级税差异常，错误信息如下");
//                    e.printStackTrace();
//                }
                callBackState = "success";
            }else if("F".equals(remitResultMsg)){
                if (cashoutRecords.getIsRefund().equals("0")){
                    BizWallet wallet = walletService.getMyWalletByUserId(userId);
                    String secProfitAmount = wallet.getProfitAmount();//获得结算账户余额
                    String secRewardAmount = wallet.getRewardAmount();// 获得奖励数据
                    String key = wallet.getSecretKey();// 获得key
                    // 解密数据
                    String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
                    String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
                    // 转换成BigDecimal类型
                    BigDecimal profitAmount = new BigDecimal(profitAmountStr);
                    BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
                    // 预支付出去的金额为
                    BigDecimal paymentMoney = cashoutRecords.getCashoutAmount();
                    // 根据cashout_type  提现类型 1-结算账户 2-奖励账户
                    String cashoutType = cashoutRecords.getCashoutType();
                    if ("1".equals(cashoutType)) {//1-结算账户
                        profitAmount = profitAmount.add(paymentMoney);
                    } else if ("2".equals(cashoutType)) {//2-奖励账户
                        rewardAmount = rewardAmount.add(paymentMoney);
                    }
                    BigDecimal walletAmount = profitAmount.add(rewardAmount);
                    // 加密
                    String profitAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(profitAmount));
                    String rewardAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(rewardAmount));
                    String walletAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(walletAmount));
                    wallet.setProfitAmount(profitAmountMoneyStr);
                    wallet.setRewardAmount(rewardAmountMoneyStr);
                    wallet.setWalletAmount(walletAmountMoneyStr);
                    wallet.setSecretKey(key);
                    // 保存钱包信息
                    walletService.saveOrUpdate(wallet);
                    // 发消息
                    String paymentFailMess = "您的提现失败，提现金额" + cashoutRecords.getCashoutAmount() + "元已经返回您的余额请注意查收，提现订单号" +
                            cashoutRecords.getVar2() + "，失败原因：交易失败" +"---错误信息："+remitResultMsg;
                    System.out.println(paymentFailMess);
                    BizMessageRecords paymentFailMessageRecords = new BizMessageRecords();
                    paymentFailMessageRecords.setMsgContent(paymentFailMess);// 消息内容
                    paymentFailMessageRecords.setMsgType(5); // 消息类型  5
                    paymentFailMessageRecords.setReadStatus(0); // 消息未读
                    paymentFailMessageRecords.setAdviceType(1); // 业务消息
                    webSocketServer.sendInfo(userId, paymentFailMessageRecords);// 发送消息
                    // 提现记录  更新状态为 0  失败
                    cashoutRecords.setCashoutStatus("0");
                    cashoutRecords.setMsgId(paymentFailMessageRecords.getMsgId()); // 存储记录中对应的消息id
                    cashoutRecords.setErrorMsg("---错误信息："+remitResultMsg);// 存储失败原因
                    cashoutRecords.setIsRefund("1");
                    cashoutRecordsService.saveOrUpdate(cashoutRecords);
                }
            }
        }
        return callBackState;
    }


}
